
using System;
using System.Runtime.InteropServices;

namespace Handrise.Mobile.BasicModal.Audio
{
	internal class WaveNative
	{
		// consts
		public const int MMSYSERR_NOERROR = 0; // no error

		public const int MM_WOM_OPEN = 0x3BB;
		public const int MM_WOM_CLOSE = 0x3BC;
		public const int MM_WOM_DONE = 0x3BD;

		public const int MM_WIM_OPEN = 0x3BE;
		public const int MM_WIM_CLOSE = 0x3BF;
		public const int MM_WIM_DATA = 0x3C0;

		public const int CALLBACK_FUNCTION = 0x00030000;    // dwCallback is a FARPROC 

		public const int TIME_MS = 0x0001;  // time in milliseconds 
		public const int TIME_SAMPLES = 0x0002;  // number of wave samples 
		public const int TIME_BYTES = 0x0004;  // current byte offset 

		// callbacks
		public delegate void WaveDelegate(IntPtr hdrvr, int uMsg, int dwUser, ref WaveHdr wavhdr, int dwParam2);

		// structs 

		[StructLayout(LayoutKind.Sequential)] public struct WaveHdr
		{
			public IntPtr lpData; // pointer to locked data buffer
			public int dwBufferLength; // length of data buffer
			public int dwBytesRecorded; // used for input only
			public IntPtr dwUser; // for client's use
			public int dwFlags; // assorted flags (see defines)
			public int dwLoops; // loop control counter
			public IntPtr lpNext; // PWaveHdr, reserved for driver
			public int reserved; // reserved for driver
		}


        [StructLayout(LayoutKind.Sequential)]
        public struct ACMSTREAMHEADER
        {
            // Instance Fields
            public int cbStruct;
            public int fdwStatus;
            public IntPtr dwUser;
            public IntPtr pbSrc;
            public int cbSrcLength;
            public int cbSrcLengthUsed;
            public IntPtr dwSrcUser;
            public IntPtr pbDst;
            public int cbDstLength;
            public int cbDstLengthUsed;
            public IntPtr dwDstUser;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
            public uint[] dwReservedDriver;
        }
        [DllImport("CoreDll.dll")]
        public static extern UInt32 acmStreamOpen(ref IntPtr phas, int had,
            IntPtr pwfxSrc, IntPtr pwfxDst, IntPtr pwfltr,
            IntPtr dwCallback, IntPtr dwInstance, int fdwOpen);

        // consts
        public const int ACM_STREAMOPENF_NONREALTIME = 0x00000004;
        public const long ACMSTREAMHEADER_STATUSF_DONE = 0x00010000L;

        [DllImport("CoreDll.dll")]
        public static extern int acmMetrics(IntPtr handle, int uMetric, ref int pMetric);

        [DllImport("CoreDll.dll")]
        public extern static int acmStreamPrepareHeader(IntPtr has, ref ACMSTREAMHEADER pash, int fdwPrepare);

        [DllImport("CoreDll.dll")]
        public extern static int acmStreamClose(IntPtr has, int fdwClose);

        [DllImport("CoreDll.dll")]
        public extern static int acmStreamConvert(IntPtr has, ref ACMSTREAMHEADER pash, int fdwConvert);

        [DllImport("CoreDll.dll")]
        public extern static int acmStreamUnprepareHeader(IntPtr has, ref ACMSTREAMHEADER pash, int fdwUnprepare);


    	// WaveOut calls
        [DllImport("CoreDll.dll")]
		public static extern int waveOutGetNumDevs();
        [DllImport("CoreDll.dll")]
		public static extern int waveOutPrepareHeader(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
        [DllImport("CoreDll.dll")]
		public static extern int waveOutUnprepareHeader(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
        [DllImport("CoreDll.dll")]
		public static extern int waveOutWrite(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
        [DllImport("CoreDll.dll")]
		public static extern int waveOutOpen(out IntPtr hWaveOut, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
        [DllImport("CoreDll.dll")]
		public static extern int waveOutReset(IntPtr hWaveOut);
        [DllImport("CoreDll.dll")]
		public static extern int waveOutClose(IntPtr hWaveOut);
        [DllImport("CoreDll.dll")]
		public static extern int waveOutPause(IntPtr hWaveOut);
        [DllImport("CoreDll.dll")]
		public static extern int waveOutRestart(IntPtr hWaveOut);
        [DllImport("CoreDll.dll")]
		public static extern int waveOutGetPosition(IntPtr hWaveOut, out int lpInfo, int uSize);
        [DllImport("CoreDll.dll")]
		public static extern int waveOutSetVolume(IntPtr hWaveOut, int dwVolume);
        [DllImport("CoreDll.dll")]
		public static extern int waveOutGetVolume(IntPtr hWaveOut, out int dwVolume);

		// WaveIn calls
        [DllImport("CoreDll.dll")]
		public static extern int waveInGetNumDevs();
        [DllImport("CoreDll.dll")]
		public static extern int waveInAddBuffer(IntPtr hwi, ref WaveHdr pwh, int cbwh);
        [DllImport("CoreDll.dll")]
		public static extern int waveInClose(IntPtr hwi);
        [DllImport("CoreDll.dll")]
		public static extern int waveInOpen(out IntPtr phwi, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
        [DllImport("CoreDll.dll")]
		public static extern int waveInPrepareHeader(IntPtr hWaveIn, ref WaveHdr lpWaveInHdr, int uSize);
        [DllImport("CoreDll.dll")]
		public static extern int waveInUnprepareHeader(IntPtr hWaveIn, ref WaveHdr lpWaveInHdr, int uSize);
        [DllImport("CoreDll.dll")]
		public static extern int waveInReset(IntPtr hwi);
        [DllImport("CoreDll.dll")]
		public static extern int waveInStart(IntPtr hwi);
        [DllImport("CoreDll.dll")]
		public static extern int waveInStop(IntPtr hwi);
	}
}
